home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / iwf12.zip / KERNEL / IMAGEIO.C < prev    next >
C/C++ Source or Header  |  1994-02-19  |  24KB  |  768 lines

  1. /*
  2. -------------------------------------------------------------------------------
  3. IMAGEIO.C  (Image Input Output)
  4.  
  5. CREATOR: Craig Muller P.Eng. 1991,1992,1993
  6.             cmuller@ccu.umanitoba.ca
  7.             Computer Vision Laboratory
  8.             University of Manitoba
  9.             Winnipeg, Manitoba. R3T 2N2
  10.             CANADA.
  11.  
  12. DESCRIPTION:
  13.  
  14. These procedures provide a general purpose interface to the image
  15. data and only have compatibility with the Windows environment.
  16.  
  17. PROCEDURES:
  18. CreateImage()    - Creates an image which can be used for storing pixel data.
  19. DestroyImage()   - Frees an image used for storing pixel data.
  20. ClearImage()     - Clears an image to zero.
  21. CopyImageData()  - Copies the pixel data from source to destination image.
  22. CopyImageRect()  - Copies a rectangle of pixels from source to destination image.
  23. CopyImageRow()   - Copies a row of pixels from source to destination image.
  24. CopyImagePal()   - Copies an image palette to a destination image
  25. DuplicateImage() - Creates a new image which is a duplicate of the original less data
  26. ReduceImage()    - Creates a new image which is a reduction of the original.
  27. ScaleImage()     - Creates a new image which scales the original into it.
  28. MirrorImage()    - Creates a new image which is a mirror of the original
  29. FlipImage()      - Creates a new image which is a flip of the original
  30. RotateImage()    - Creates a new image which is a rotation of the original
  31. GetImagePixel()  - Gets a pixel from an image at x,y and stores it in dn.
  32. SetImagePixel()  - Sets a pixel value in the source frame buffer at x,y to a value of dn.
  33. GetImageScan()   - Gets a raster line from an image at line y and stores it at dn.
  34. GetImageRow()    - Gets a row of pixels from an image and stores it at dn.
  35. PutImageRow()    - Puts a row of pixels from a buffer into an image
  36. SetImageRow()    - Sets a row of pixels to a value
  37. GetImageCol()    - Gets a column of pixels from an image and stores it at dn.
  38. PutImageCol()    - Puts a column of pixels from a buffer into an image
  39. SetImageCol()    - Sets a column of pixels to a value
  40. GetImageRect()   - Cuts a rectangle from an image and stores it in the buffer.
  41. PutImageRect()   - Pastes a rectangle from the buffer to an image.
  42. SetImageRect()   - Sets a rectangular region of pixels to a value
  43. ImageMessage()   - Puts an error message on the screen
  44. -------------------------------------------------------------------------------
  45. */
  46. #include <windows.h>
  47.  
  48. #pragma hdrstop
  49.  
  50. #include <stdio.h>
  51. #include <dos.h>
  52. #include <math.h>
  53. #include <mem.h>
  54. #include <alloc.h>
  55. #include <string.h>
  56.  
  57. #include "kernel.h"
  58.  
  59.  
  60. void CopyImageRow(IMAGE *s_image,IMAGE *d_image,int x,int y,int cb);
  61. void CopyImageRect(IMAGE *s_image,IMAGE *d_image,RECT *rs);
  62.  
  63.  
  64. /*
  65. ---------------------------------------------------------------------
  66. ImageMessage() - Puts an error message on the screen
  67. ~~~~~~~~~~
  68.  
  69. COMMENTS:
  70. ---------------------------------------------------------------------
  71. */
  72. void ImageMessage(char *sz)
  73.    {
  74.    MessageBeep(MB_ICONEXCLAMATION);
  75.     MessageBox(NULL,sz,"KERNEL ERROR (FBIO)",MB_OK | MB_ICONEXCLAMATION);
  76.    }
  77.  
  78.  
  79. /*
  80. ---------------------------------------------------------------------
  81. IMAGE *CreateImage(int w,int h)
  82. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  83. This procedure allows the user to create a memory Frame Buffer (IMAGE)
  84. in the PC memory space. There is no limit on the number of images
  85. that can be created as long as there is memory space available.
  86.  
  87. Parameters:
  88.  
  89.    w - width of image
  90.    h - height of image
  91.  
  92. Return value:
  93.  
  94.    (IMAGE *) - pointer to the new image structure.
  95.  
  96. ---------------------------------------------------------------------
  97. */
  98. IMAGE *CreateImage(int w,int h)
  99.    {
  100.    char sz[80];
  101.    int i;
  102.     IMAGE *image;
  103.  
  104.    // Allocate local memory space for the data structure for the IMAGE object.
  105.    image = (IMAGE *)LocalAlloc(LPTR,sizeof(IMAGE));
  106.    if (!image)
  107.       {
  108.       ImageMessage("Unable to Allocate Local Memory");
  109.       return(image);
  110.       }
  111.  
  112.    if (w>MAXW)
  113.       {
  114.       sprintf(sz,"Width exceeds %d pixels, image will be truncated",MAXW);
  115.       ImageMessage(sz);
  116.       w = MAXW;
  117.       }
  118.  
  119.    if (h>MAXH)
  120.       {
  121.       sprintf(sz,"Height exceeds %d pixels, image will be truncated",MAXW);
  122.       ImageMessage(sz);
  123.       h = MAXH;
  124.       }
  125.  
  126.     strcpy(image->comment,"No Comments");         // Default comment string
  127.     strcpy(image->fspec,"Untitled");              // Default file name string
  128.     image->color  = FALSE;                        // Image by default is gray
  129.     image->hres   = w;                            // Set the image width
  130.     image->vres   = h;                            // Set the image height
  131.     image->depth  = 8;                            // Only uses 8 bit images
  132.     image->palsize= 256;                          // Default palette entries used
  133.     image->gamma  = 0.5;                          // Default gamma value
  134.  
  135.     // *** IMPORTANT ***
  136.     // Even though the width of an image can be any value, when the image
  137.     // is displayed in Windows the bitmap scan must fit on a 32 bit boundary
  138.     // or else the display will appear all garbled. Scansize is used for this.
  139.     image->scansize = (w%4) ? (w/4+1)*4 : w;      // Must fit 32 bit boundary.
  140.  
  141.     SetRect(&image->rc,0,0,image->hres-1,image->vres-1);   // Set default client rectangle
  142.  
  143.     // Since the default image is gray set the input and output LUTS
  144.     // to a gray scale.
  145.     for (i=0; i<256; ++i)
  146.         {
  147.         image->ILUT[i] = i;
  148.         }
  149.     for (i=0; i<256; ++i)
  150.         {
  151.         image-> Pal[i].peRed   = i;
  152.         image-> Pal[i].peGreen = i;
  153.         image-> Pal[i].peBlue  = i;
  154.         image-> Pal[i].peFlags = 0;
  155.       image-> LUT[i].peRed   = i;
  156.       image-> LUT[i].peGreen = i;
  157.       image-> LUT[i].peBlue  = i;
  158.       image-> LUT[i].peFlags = 0;
  159.         }
  160.  
  161.    // Allocate global memory for holding the image data.
  162.    image->hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,(DWORD)image->scansize*image->vres);
  163.    if (!image->hData)
  164.       {
  165.       ImageMessage("Unable to Allocate Global Memory");
  166.       image = (IMAGE *)LocalFree((LOCALHANDLE)image);
  167.       }
  168.  
  169.    return(image);                                   // Return a pointer to the new image
  170.    }
  171.  
  172.  
  173. /*
  174. ---------------------------------------------------------------------
  175. IMAGE *DestroyImage(IMAGE *image)
  176. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  177. Destroys a Frame Buffer object by first freeing any data memory and
  178. then freeing the object structure. The object is returned if it cannot
  179. be destroyed for any reason, otherwise NULL is returned if OK.
  180.  
  181. Parameters:
  182.  
  183.    image - pointer to image to be destroyed
  184.  
  185. Return value:
  186.  
  187.    (IMAGE *) - null pointer to image if successful.
  188.  
  189. ---------------------------------------------------------------------
  190. */
  191. IMAGE *DestroyImage(IMAGE *image)
  192.    {
  193.    if (image)                                       // If the image is valid
  194.       {
  195.       if (image->hData)                             // If the data is valid
  196.          image->hData = GlobalFree(image->hData);      // Free the image data
  197.       if (image->hData)                             // If the data is still valid
  198.          {                                       // It was unable to free it
  199.          ImageMessage("Unable to Free Global Memory");
  200.          return(image);
  201.          }
  202.       image = (IMAGE *)LocalFree((LOCALHANDLE)image);     // Free the local structure
  203.       if (image)                                    // If it is still there
  204.          {                                       // It was unable to free it
  205.          ImageMessage("Unable to Free Local Memory");
  206.          return(image);
  207.          }
  208.       }
  209.  
  210.    return(image);                                   // Return image pointer
  211.    }
  212.  
  213. /*
  214. -------------------------------------------------------------------------------
  215. IMAGE *DuplicateImage(IMAGE *image)
  216. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  217. This procedure allows the user to duplicate a image structure
  218. in the PC memory space. There is no limit on the number of memory FBs
  219. that can be created as long as there is memory space available.  The orginal
  220. image is not destroyed.
  221.  
  222. Parameters:
  223.  
  224.    image - pointer to source image
  225.  
  226. Return value:
  227.  
  228.    (IMAGE *) - null pointer to the new image if successful.
  229.  
  230. -------------------------------------------------------------------------------
  231. */
  232. IMAGE *DuplicateImage(IMAGE *image)
  233.    {
  234.     IMAGE *new_image;
  235.  
  236.    // Allocate local memory space for the data structure for the IMAGE object.
  237.    new_image = (IMAGE *)LocalAlloc(LPTR,sizeof(IMAGE));
  238.    if (!new_image)
  239.       {
  240.       ImageMessage("Unable to Allocate Local Memory");
  241.       return(new_image);
  242.         }
  243.  
  244.     // Copy structure information
  245.     memcpy(new_image,image,sizeof(IMAGE));
  246.  
  247.    // Allocate global memory for holding the new_image data.
  248.    new_image->hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,(DWORD)new_image->scansize*new_image->vres);
  249.    if (!new_image->hData)
  250.       {
  251.         ImageMessage("Unable to Allocate Global Memory");
  252.       new_image = (IMAGE *)LocalFree((LOCALHANDLE)new_image);
  253.       return(new_image);
  254.       }
  255.  
  256.    return(new_image);
  257.    }
  258.  
  259.  
  260.  
  261. /*
  262. -------------------------------------------------------------------------------
  263. void CopyImageData(IMAGE *s_image,IMAGE *d_image)
  264. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  265. Copies the source frame buffer data to the destination frame buffer
  266.  
  267. Parameters:
  268.    s_image - pointer to source image
  269.    d_image - pointer to destination image
  270. -------------------------------------------------------------------------------
  271. */
  272. void CopyImageData(IMAGE *s_image,IMAGE *d_image)
  273.    {
  274.    RECT rs;
  275.  
  276.    SetRect(&rs,0,0,d_image->hres,d_image->vres);
  277.    CopyImageRect(s_image,d_image,&rs);
  278.     }
  279.  
  280.  
  281. /*
  282. --------------------------------------------------------------------------
  283. void CopyImageRect(IMAGE *image,RECT *r,BYTE *buf)
  284.  
  285. DESCRIPTION:
  286. This procedure copies a rectanglar region from the memory IMAGE to a
  287. buffer. This allows the programmer to extract a region from the image
  288. and process it without changing the original data.
  289. --------------------------------------------------------------------------
  290. */
  291. void CopyImageRect(IMAGE *s_image,IMAGE *d_image,RECT *rs)
  292.    {
  293.    int y;
  294.    RECT rd,ro;
  295.  
  296.    SetRect(&rd,0,0,d_image->hres,d_image->vres);
  297.    IntersectRect(&ro,rs,&rd);
  298.  
  299.    for (y=ro.top; y<ro.bottom; ++y)
  300.       CopyImageRow(s_image,d_image,ro.left,y,ro.right-ro.left);
  301.    }
  302.  
  303.  
  304. /*
  305. -------------------------------------------------------------------------------
  306. void CopyImageRow(IMAGE *s_image,IMAGE *d_image,int x,int y,int cb)
  307.  
  308. Copies the source frame buffer data to the destination frame buffer
  309. Parameters:
  310.    s_image - pointer to source image
  311.    d_image - pointer to destination image
  312. -------------------------------------------------------------------------------
  313. */
  314. void CopyImageRow(IMAGE *s_image,IMAGE *d_image,int x,int y,int cb)
  315.    {
  316.    int i;
  317.    BYTE huge *hpDataSrc;
  318.    BYTE huge *hpDataDst;
  319.    BYTE huge *hpRowS;
  320.    BYTE huge *hpRowD;
  321.  
  322.     hpDataSrc = (BYTE huge *)GlobalLock(s_image->hData);// Lock the IMAGE memory
  323.    hpDataDst = (BYTE huge *)GlobalLock(d_image->hData);// Lock the IMAGE memory
  324.  
  325.    if (x+cb > d_image->hres)
  326.        cb = d_image->hres-x;
  327.  
  328.    // Compute a pointer to the start of each image memory slice.
  329.    hpRowD = MK_HPIMAGE(d_image,hpDataDst,x,y);
  330.    hpRowS = MK_HPIMAGE(s_image,hpDataSrc,x,y);
  331.  
  332.    // Copy a row of pixel numbers from the source image to destination.
  333.     for (i=0; i<cb; ++i)
  334.       *(hpRowD+i) = *(hpRowS+i);
  335.  
  336. // *** DIRECT MEM COPY - FAST, BUT NEED TO CURE SEGMENT WRAPPING PROBLEM ***
  337. // _fmemcpy(hpRowD,hpRowS,cb);
  338.  
  339.    GlobalUnlock(s_image->hData);                 // Unlock the IMAGE memory
  340.    GlobalUnlock(d_image->hData);                 // Unlock the IMAGE memory
  341.     }
  342.  
  343. /*
  344. -------------------------------------------------------------------------------
  345. void CopyImagePal(IMAGE *s_image,IMAGE *d_image)
  346. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  347. Copies the palette and lookup table info from source to destination.
  348.  
  349. Parameters:
  350.    s_image - pointer to source image
  351.    d_image - pointer to destination image
  352. -------------------------------------------------------------------------------
  353. */
  354. void CopyImagePal(IMAGE *s_image,IMAGE *d_image)
  355.     {
  356.     int i;
  357.  
  358.     // Copy the current palette and lookup table info
  359.     for (i=0; i<256; ++i)
  360.         {
  361.         d_image->Pal[i].peRed   = s_image->Pal[i].peRed;
  362.         d_image->Pal[i].peGreen = s_image->Pal[i].peGreen;
  363.         d_image->Pal[i].peBlue  = s_image->Pal[i].peBlue;
  364.         d_image->Pal[i].peFlags = 0;
  365.         d_image->LUT[i].peRed   = s_image->LUT[i].peRed;
  366.         d_image->LUT[i].peGreen = s_image->LUT[i].peGreen;
  367.         d_image->LUT[i].peBlue  = s_image->LUT[i].peBlue;
  368.         d_image->LUT[i].peFlags = 0;
  369.         }
  370.     }
  371.  
  372.  
  373. /*
  374. -------------------------------------------------------------------------------
  375. void ClearImage(IMAGE *image)
  376. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  377. Clears the frame buffer data to zero.
  378.  
  379. Parameters:
  380.  
  381.    image - pointer to image to be cleared
  382.  
  383. Return value:
  384.  
  385.    none
  386.  
  387. -------------------------------------------------------------------------------
  388. */
  389. void ClearImage(IMAGE *image)
  390.    {
  391.    int x,y;
  392.    BYTE huge *hpData;
  393.  
  394.    hpData = (BYTE huge *)GlobalLock(image->hData);    /* Lock the IMAGE memory   */
  395.  
  396.    for (y=image->rc.top; y<image->rc.bottom; ++y)
  397.       for (x=image->rc.left; x<image->rc.right; ++x)
  398.          *(hpData+(DWORD)(image->vres-1-y)*image->scansize+x)=0;
  399.  
  400.    GlobalUnlock(image->hData);                         /* Unlock the IMAGE memory */
  401.    }
  402.  
  403.  
  404. /*
  405. --------------------------------------------------------------------------
  406. GetImagePixel()
  407. ~~~~~~~~~~~~
  408.  
  409. This procedure gets a pixel from the memory IMAGE and stores it into a buffer.
  410. NOTE: to index into the image memory like an array, the index
  411. value must be a long variable type, NOT just cast to long.
  412. --------------------------------------------------------------------------
  413. */
  414. int GetImagePixel(IMAGE *image,int x,int y,BYTE *dn)
  415.    {
  416.    BYTE huge *hpData;
  417.  
  418.     // Lock the image data from moving
  419.     hpData = (BYTE huge *)GlobalLock(image->hData);
  420.  
  421.     // Copy the pixel data value to the buffer
  422.     *dn = *(hpData+(DWORD)(image->vres-1-y)*image->scansize+x);
  423.  
  424.     // Unlock the image data
  425.     GlobalUnlock(image->hData);
  426.  
  427.     return(0);
  428.    }
  429.  
  430.  
  431.  
  432. /*
  433. --------------------------------------------------------------------------
  434. int  SetImagePixel(IMAGE *image,int x,int y,int dn)
  435.  
  436. DESCRIPTION:
  437. This procedure puts a pixel from the buffer into the memory IMAGE.
  438. --------------------------------------------------------------------------
  439. */
  440. int  SetImagePixel(IMAGE *image,int x,int y,BYTE dn)
  441.    {
  442.     BYTE huge *hpData;
  443.  
  444.     // Lock the image data from moving
  445.     hpData = (BYTE huge *)GlobalLock(image->hData);
  446.  
  447.     // Copy the buffer value to the pixel data
  448.     *(hpData+(DWORD)(image->vres-1-y)*image->scansize+x) = dn;
  449.  
  450.     // Unlock the image data
  451.     GlobalUnlock(image->hData);
  452.  
  453.     return(0);
  454.    }
  455.  
  456.  
  457. /*
  458. --------------------------------------------------------------------------
  459. int  GetImageScan(IMAGE *image,int y,BYTE *dn)
  460.  
  461. DESCRIPTION:
  462. This procedure gets a row of bytes from the memory IMAGE and stores
  463. it into a buffer. This allows the user to extract a horizontal slice
  464. of the image.
  465. NOTE: to index into the image memory like an array, the index
  466. value must be a long variable type, NOT just cast to long.
  467. --------------------------------------------------------------------------
  468. */
  469. int GetImageScan(IMAGE *image,int y,BYTE *dn)
  470.    {
  471.    WORD x;
  472.    BYTE huge *hpData;
  473.  
  474.     // Lock the image data from moving
  475.     hpData = (BYTE huge *)GlobalLock(image->hData);
  476.  
  477.     for (x=0; x<image->hres; ++x)
  478.       *(dn+x) = *(hpData+(DWORD)(image->vres-1-y)*image->scansize+x);
  479.  
  480.     // Unlock the image data
  481.     GlobalUnlock(image->hData);
  482.  
  483.     return(0);
  484.     }
  485.  
  486.  
  487.  
  488. /*
  489. --------------------------------------------------------------------------
  490. int  GetImageRow(IMAGE *image,int x,int y,BYTE *dn,int cb)
  491.  
  492. DESCRIPTION:
  493. This procedure gets a row of bytes from the memory IMAGE and stores
  494. it into a buffer. This allows the user to extract a horizontal slice
  495. of any length from the image data. The slice can be longer or shorter
  496. than the length of a single raster line.
  497. NOTE: to index into the image memory like an array, the index
  498. value must be a long variable type, NOT just cast to long.
  499. --------------------------------------------------------------------------
  500. */
  501. int  GetImageRow(IMAGE *image,int x,int y,BYTE *dn,int cb)
  502.     {
  503.     int n;
  504.     BYTE huge *hpData;
  505.  
  506.     // Lock the image data from moving
  507.     hpData = (BYTE huge *)GlobalLock(image->hData);
  508.  
  509.     // If the count is positive, copy the pixel data normally
  510.     if (cb>0)
  511.         for (n=0; n<cb; ++n)
  512.             if (x+n < image->hres)
  513.                 dn[n]  = *(hpData + (DWORD)(image->vres-1-y)*image->scansize + x + n);
  514.  
  515.     // If the count is negative, copy the pixel data in reverse
  516.     if (cb<0)
  517.         for (n=0; n>cb; --n)
  518.             if (x+n >= 0)
  519.                 dn[-n] = *(hpData + (DWORD)(image->vres-1-y)*image->scansize + x + n);
  520.  
  521.     // Unlock the image data
  522.     GlobalUnlock(image->hData);
  523.  
  524.     return(0);
  525.     }
  526.  
  527.  /*
  528. --------------------------------------------------------------------------
  529. int  PutImageRow(IMAGE *image,int x,int y,BYTE *dn,int cb)
  530.  
  531. DESCRIPTION:
  532. NOTE: to index into the image memory like an array, the index
  533. value must be a long variable type, NOT just cast to long.
  534. --------------------------------------------------------------------------
  535. */
  536. int  PutImageRow(IMAGE *image,int x,int y,BYTE *dn,int cb)
  537.    {
  538.    int n;
  539.    BYTE huge *hpData;
  540.  
  541.     // Lock the image data from moving
  542.     hpData = (BYTE huge *)GlobalLock(image->hData);
  543.  
  544.     // If the count is positive, copy the pixel data normally
  545.     if (cb>0)
  546.       for (n=0; n<cb; ++n)
  547.          if (x+n < image->hres)
  548.             *(hpData + (DWORD)(image->vres-1-y)*image->scansize + x + n) = dn[n];
  549.  
  550.     // If the count is negative, copy the pixel data in reverse
  551.     if (cb<0)
  552.       for (n=0; n>cb; --n)
  553.          if (x+n >= 0)
  554.             *(hpData + (DWORD)(image->vres-1-y)*image->scansize + x + n) = dn[-n];
  555.  
  556.     // Unlock the image data
  557.     GlobalUnlock(image->hData);
  558.  
  559.     return(0);
  560.    }
  561.  
  562.  
  563.  
  564. /*
  565. --------------------------------------------------------------------------
  566. int  GetImageCol(IMAGE *image,int x,int y,BYTE *dn,int cb)
  567.  
  568. DESCRIPTION:
  569. This procedure gets a column of bytes from the memory IMAGE and stores
  570. it into a buffer. This allows the user to extract a horizontal slice
  571. of any length from the image data. The slice can be shorter but not
  572. longer than the height of the IMAGE.
  573. NOTE: to index into the image memory like an array, the index
  574. value must be a long variable type, NOT just cast to long.
  575.  
  576. RETURN: Integer indicating success(0) or fail(-1).
  577. --------------------------------------------------------------------------
  578. */
  579. int GetImageCol(IMAGE *image,int x,int y,BYTE *dn,int cb)
  580.    {
  581.    int n;
  582.    BYTE huge *hpData;
  583.  
  584.     // Lock the image data from moving
  585.     hpData = (BYTE huge *)GlobalLock(image->hData);
  586.  
  587.     // If the count is positive, copy the pixel data normally
  588.     if (cb>0)
  589.       for (n=0; n<cb; ++n)
  590.          if (y+n < image->vres)
  591.             dn[n]  = *(hpData + (DWORD)(image->vres-1-(y+n))*image->scansize + x);
  592.  
  593.     // If the count is negative, copy the pixel data in reverse
  594.     if (cb<0)
  595.         for (n=0; n>cb; --n)
  596.             if (y+n >= 0)
  597.                 dn[-n] = *(hpData + (DWORD)(image->vres-1-(y+n))*image->scansize + x);
  598.  
  599.     // Unlock the image data
  600.     GlobalUnlock(image->hData);
  601.  
  602.     return(0);
  603.    }
  604.  
  605.  
  606. /*
  607. --------------------------------------------------------------------------
  608. int  PutImageCol(IMAGE *image,int x,int y,BYTE *dn,int cb)
  609.  
  610. DESCRIPTION:
  611. This procedure gets a column of bytes from the memory IMAGE and stores
  612. it into a buffer. This allows the user to extract a horizontal slice
  613. of any length from the image data. The slice can be shorter but not
  614. longer than the height of the IMAGE.
  615. NOTE: to index into the image memory like an array, the index
  616. value must be a long variable type, NOT just cast to long.
  617.  
  618. RETURN: Integer indicating success(0) or fail(-1).
  619. --------------------------------------------------------------------------
  620. */
  621. int PutImageCol(IMAGE *image,int x,int y,BYTE *dn,int cb)
  622.    {
  623.    int n;
  624.     BYTE huge *hpData;
  625.  
  626.     // Lock the image data from moving
  627.     hpData = (BYTE huge *)GlobalLock(image->hData);
  628.  
  629.     // If the count is positive, copy the pixel data normally
  630.     if (cb>0)
  631.       for (n=0; n<cb; ++n)
  632.          if (y+n < image->vres)
  633.             *(hpData + (DWORD)(image->vres-1-(y+n))*image->scansize + x) = dn[n];
  634.  
  635.     // If the count is negative, copy the pixel data in reverse
  636.     if (cb<0)
  637.       for (n=0; n>cb; --n)
  638.          if (y+n >= 0)
  639.             *(hpData + (DWORD)(image->vres-1-(y+n))*image->scansize + x) = dn[-n];
  640.  
  641.     // Unlock the image data
  642.     GlobalUnlock(image->hData);
  643.  
  644.     return(0);
  645.    }
  646.  
  647.  
  648. /*
  649. --------------------------------------------------------------------------
  650. int  GetImageRect(IMAGE *image,RECT *r,BYTE *buf)
  651.  
  652. DESCRIPTION:
  653. This procedure copies a rectanglar region from the memory IMAGE to a
  654. buffer. This allows the programmer to extract a region from the image
  655. and process it without changing the original data.
  656. --------------------------------------------------------------------------
  657. */
  658. int  GetImageRect(IMAGE *image,RECT *rc,BYTE *buf)
  659.    {
  660.    int x0,y0,y,w,h;
  661.  
  662.    x0 = rc->left;
  663.    y0 = rc->top;
  664.    w  = rc->right - rc->left;
  665.    h  = rc->bottom - rc->top;
  666.  
  667.    for (y=0; y<h; y++)
  668.       GetImageRow(image,x0,y0+y,buf+(y*w),w);
  669.  
  670.    return(0);
  671.    }
  672.  
  673.  
  674. /*
  675. --------------------------------------------------------------------------
  676. int  PutImageRect(IMAGE *image,RECT *r,BYTE *buf)
  677.  
  678. DESCRIPTION:
  679. This procedure copies a rectanglar region from the buffer to the memory
  680. IMAGE. This allows the programmer to paste a processed region to the image.
  681. --------------------------------------------------------------------------
  682. */
  683. int  PutImageRect(IMAGE *image,RECT *rc,BYTE *buf)
  684.    {
  685.    int x0,y0,y,w,h;
  686.  
  687.    x0 = rc->left;
  688.    y0 = rc->top;
  689.    w  = rc->right - rc->left;
  690.    h  = rc->bottom - rc->top;
  691.  
  692.    for (y=0; y<h; y++)
  693.       PutImageRow(image,x0,y0+y,buf+(y*w),w);
  694.  
  695.    return(0);
  696.    }
  697.  
  698.  
  699. /*
  700. --------------------------------------------------------------------------
  701. int  SetImageRow(IMAGE *image,int x,int y,int Length,BYTE dn)
  702.  
  703. DESCRIPTION:
  704. This procedure puts a line from a buffer into the memory IMAGE.
  705. NOTE: A length of 0 is one pixel long. A length of 1 is two pixels
  706. long. That is why length is incremented before being used.
  707. --------------------------------------------------------------------------
  708. */
  709. int  SetImageRow(IMAGE *image,int x,int y,int Length,BYTE dn)
  710.    {
  711.    if (x+Length > image->scansize)
  712.       Length=image->scansize-x;
  713.    while (Length--)
  714.       SetImagePixel(image,x++,y,dn);
  715.  
  716.    return(0);
  717.    }
  718.  
  719.  
  720.  
  721. /*
  722. --------------------------------------------------------------------------
  723. int  SetImageCol(IMAGE *image,int x,int y,int Length,BYTE dn)
  724.  
  725. DESCRIPTION:
  726. This procedure puts a line from a buffer into the memory IMAGE.
  727.  
  728. NOTE: A length of 0 is one pixel long. A length of 1 is two pixels
  729. long. That is why length is incremented before being used.
  730. --------------------------------------------------------------------------
  731. */
  732. int  SetImageCol(IMAGE *image,int x,int y,int Length,BYTE dn)
  733.    {
  734.    if (x<0 || y<0 || x>=image->scansize || y>=image->vres)         /* Check bounds         */
  735.       return(-1);
  736.  
  737.    if (y+Length > image->vres)
  738.       Length=image->vres-y;
  739.    while (Length--)
  740.       SetImagePixel(image,x,y++,dn);
  741.  
  742.    return(0);
  743.    }
  744.  
  745.  
  746.  
  747.  
  748.  /*
  749. --------------------------------------------------------------------------
  750. SetImageRect() - Draws a filled rectanglar region in the memory IMAGE
  751. ~~~~~~~~~~~~~~
  752.  
  753. DESCRIPTION:
  754. Draws a filled rectanglar region in the memory IMAGE with the grey level
  755. given in the byte buffer.
  756. --------------------------------------------------------------------------
  757. */
  758. int  SetImageRect(IMAGE *image,RECT *r,BYTE dn)
  759.    {
  760.    SetImageCol(image,r->left ,r->top   ,r->bottom - r->top,dn);
  761.     SetImageCol(image,r->right,r->top   ,r->bottom - r->top,dn);
  762.    SetImageRow(image,r->left ,r->top   ,r->bottom - r->top,dn);
  763.     SetImageRow(image,r->left ,r->bottom,r->bottom - r->top,dn);
  764.  
  765.    return(0);
  766.    }
  767.  
  768.